﻿Imports System.IO


Namespace filedb

    ''' <summary>
    ''' Provides methods for store data with file name and extension type as key. example: joehom.username, joehom is the value of username. 
    ''' </summary>
    ''' <remarks></remarks>
    Public Class filevalue
        'created by: Sum
        'created date:14/03/2012
        'description: use filename to store value, file name=value,extension=key, example: joehom.username, "joehom" is the value, "username" is the key 
        'modified by: sum 
        'modified date: 20/3/2012
        'description: add encode and decode
        'modified by: Sum
        'modified date: 11/4/2012
        'desc: add crlf,cr,lf encode and decode
        'add try and catch to addvalue and getvalue function

        Private _rootFolder As String = String.Empty
        ''' <summary>
        ''' Initializes a new instance of the filevalue
        ''' </summary>
        ''' <param name="rootFolder">physical file path</param>
        ''' <remarks></remarks>
        Public Sub New(ByVal rootFolder As String)
            If rootFolder.Last <> "\"c Then
                rootFolder = rootFolder & "\"
            End If
            _rootFolder = rootFolder
        End Sub

        ''' <summary>
        ''' Get list of file info in the root folder
        ''' </summary>
        ''' <returns>list of fileinfo</returns>
        ''' <remarks></remarks>
        Private Function GetFileList() As List(Of FileInfo)
            Dim List As List(Of FileInfo) = New List(Of FileInfo)
            Try
                ' make a reference to a directory
                Dim di As New IO.DirectoryInfo(_rootFolder)
                Dim diar1 As IO.FileInfo() = di.GetFiles()
                Dim dra As IO.FileInfo

                'list the names of all files in the specified directory
                For Each dra In diar1
                    List.Add(dra)
                Next
            Catch ex As Exception
                Throw ex
            End Try

            Return List
        End Function


        ''' <summary>
        ''' Get value by file extension
        ''' </summary>
        ''' <param name="extension">key</param>
        ''' <returns>value</returns>
        ''' <remarks></remarks>
        Public Function GetValue(ByVal extension As String) As String
            Dim rev As String = String.Empty
            Try
                If extension.First() <> "."c Then
                    extension = "." & extension

                End If

                Dim list As List(Of FileInfo) = GetFileList()

                For Each F As FileInfo In list
                    If F.Extension = extension Then
                        rev = F.Name.Replace(extension, String.Empty)
                    End If
                Next
            Catch ex As Exception
                Throw ex
            End Try

            'decode 
            rev = decode(rev)
            Return rev
        End Function
        ''' <summary>
        ''' Get value by file extension
        ''' </summary>
        ''' <param name="extension">key</param>
        ''' <param name="mustExist">whether the specified key must exsit in file value</param>
        ''' <param name="defaultValue">if mustExist set to true and can't find this specified key</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetValue(ByVal extension As String, ByVal mustExist As Boolean, ByVal defaultValue As String) As String
            Dim rev As String = String.Empty
            Try
                rev = GetValue(extension)

                If rev = String.Empty Then
                    If mustExist Then
                        AddValue(defaultValue, extension)
                        rev = GetValue(extension)
                    End If
                End If
            Catch ex As Exception
                Throw ex
            End Try

            Return rev
        End Function
        ''' <summary>
        ''' Add a new value
        ''' </summary>
        ''' <param name="value">value</param>
        ''' <param name="extension">key</param>
        ''' <returns>if successful added return true otherwise return false</returns>
        ''' <remarks></remarks>
        Public Function AddValue(ByVal value As String, ByVal extension As String) As Boolean
            Try


                If extension.First() <> "."c Then
                    extension = "." & extension

                End If

                'check length
                If Not checkLength(value) Then
                    Return False
                End If

                'encode value before store
                value = encode(value)

                Dim filename = value & extension
                'check file

                'delete existing file with same extension
                For Each f In Directory.GetFiles(_rootFolder, "*" & extension & "", SearchOption.AllDirectories)
                    File.Delete(f)
                Next

                Dim stream As FileStream = File.Create(_rootFolder & filename)
                stream.Close()

                'If Not File.Exists(filename) Then
                '    Dim stream As FileStream = File.Create(_rootFolder & filename)
                '    stream.Close()
                'Else
                '    File.Delete(_rootFolder & filename)
                '    Dim stream As FileStream = File.Create(_rootFolder & filename)
                '    stream.Close()
                'End If
                Return True
            Catch ex As Exception
                Throw ex
            End Try

        End Function


        ''' <summary>
        ''' filname maximum is 260 characters, this function is ensure that value does not more than 260 characters
        ''' </summary>
        ''' <param name="value">value</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function checkLength(ByVal value As String) As Boolean
            If value.Length > 260 Then
                Return False
            Else
                Return True
            End If
        End Function


        ''' <summary>
        ''' replace forbidden character 
        ''' </summary>
        ''' <param name="value">value</param>
        ''' <returns>encoded value</returns>
        ''' <remarks></remarks>
        Private Function encode(ByVal value As String) As String
            value = value.Replace("\"c, "[1]")
            value = value.Replace("/"c, "[2]")
            value = value.Replace("*"c, "[3]")
            value = value.Replace(":"c, "[4]")
            value = value.Replace("?"c, "[5]")
            value = value.Replace("""", "[6]")
            value = value.Replace("<"c, "[7]")
            value = value.Replace(">"c, "[8]")
            value = value.Replace("|"c, "[9]")
            value = value.Replace(vbCrLf, "[10]")
            value = value.Replace(vbCr, "[11]")
            value = value.Replace(vbLf, "[12]")
            Return value
        End Function

        ''' <summary>
        ''' restore forbidden character 
        ''' </summary>
        ''' <param name="value">encoded value</param>
        ''' <returns>decoded value</returns>
        ''' <remarks></remarks>
        Private Function decode(ByVal value As String) As String
            value = value.Replace("[1]", "\"c)
            value = value.Replace("[2]", "/"c)
            value = value.Replace("[3]", "*"c)
            value = value.Replace("[4]", ":"c)
            value = value.Replace("[5]", "?"c)
            value = value.Replace("[6]", """")
            value = value.Replace("[7]", "<"c)
            value = value.Replace("[8]", ">"c)
            value = value.Replace("[9]", "|"c)
            value = value.Replace("[10]", vbCrLf)
            value = value.Replace("[11]", vbCr)
            value = value.Replace("[12]", vbLf)
            Return value
        End Function

    End Class
End Namespace

